/**
* 
* Copyright [2007] [Sunny Liu]
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/
package ${appConfig.outputPackageName}.dao.hibernate;


import ${appConfig.outputPackageName}.model.${entity.javaName};
import ${appConfig.outputPackageName}.dao.${entity.javaName}DAO;

import java.util.List;

import java.util.Hashtable;
import java.util.ArrayList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;



public class ${entity.javaName}DAOImpl
extends HibernateDaoSupport
implements ${entity.javaName}DAO
{
	private static Logger log = LoggerFactory.getLogger(${entity.javaName}DAOImpl.class);
	private Hashtable dataStore = null;
	
	
	public ${entity.javaName}DAOImpl()
	{
		super();		
	}
	
	
	/**
	* this is a default find method for DAO, it will list all table contents
	* or limited by query.
	*/
	public List findAll${entity.javaName}()
	{
		
		if(log.isDebugEnabled()) log.debug("Entering findAll${entity.javaName}()");
		List ret = this.getHibernateTemplate().find(
            "from ${outputPackageName}.model.${entity.javaName} ${entity.normalizedJavaName}");		
		if(log.isDebugEnabled()) log.debug("Exiting findAll${entity.javaName}()");	
		return ret;
	}
	
	
	<#if entity.hasPrimaryKey >	
	/**
	* Find domain model object from underline table base upon
	* primary key.
	*/	
	public ${entity.javaName} find${entity.javaName}ByKey(<#list entity.primaryKeyColumns as attribute>${attribute.javaType} ${attribute.javaName} <#if attribute_has_next>, </#if></#list>)
	{
		
		if(log.isDebugEnabled()) log.debug("Entering find${entity.javaName}ByKey()");
		Object[] keyParams = new Object[]{
		<#list entity.primaryKeyColumns as attribute>
		<#if attribute.javaType=="int">new Integer(${attribute.javaName})<#elseif attribute.javaType=="long">new Long(${attribute.javaName})<#elseif attribute.javaType=="short">new Short(${attribute.javaName})<#elseif attribute.javaType=="byte">new Byte(${attribute.javaName})<#elseif attribute.javaType=="char">new Character(${attribute.javaName})<#else>${attribute.javaName}</#if><#if attribute_has_next>, </#if>
		</#list>
		};
		String hql = "from ${outputPackageName}.model.${entity.javaName} ${entity.normalizedJavaName} where <#list entity.primaryKeyColumns as attribute>${entity.normalizedJavaName}.${attribute.javaName}=?<#if attribute_has_next> and </#if></#list>";
		List rs = this.getHibernateTemplate().find(hql, keyParams);	
		${entity.javaName} ret = null;
		if (rs.size()==1)
		{
			ret = (${entity.javaName}) rs.get(0);
		}else if(rs.size()>1){
			ret = (${entity.javaName}) rs.get(0);
			log.warn("More than one Object found. Primarykey=" + keyParams);
		}else{
			log.warn("Object not found. Primarykey=" + keyParams);			
		}			
		if(log.isDebugEnabled()) log.debug("Exiting find${entity.javaName}ByKey() Primarykey=" + ret);	
		return ret;
	}
	
	public ${entity.javaName} find${entity.javaName}ByKey(${entity.javaName} ${entity.normalizedJavaName})
	{
		if(log.isDebugEnabled()) log.debug("Entering find${entity.javaName}ByKey() Primarykey=" + ${entity.normalizedJavaName});
		Object[] keyParams = new Object[]{
		<#list entity.primaryKeyColumns as attribute>
		<#if attribute.javaType=="int">new Integer(${entity.normalizedJavaName}.get${attribute.setterGetterName}())<#elseif attribute.javaType=="long">new Long(${entity.normalizedJavaName}.get${attribute.setterGetterName}())<#elseif attribute.javaType=="short">new Short(${entity.normalizedJavaName}.get${attribute.setterGetterName}())<#elseif attribute.javaType=="byte">new Byte(${entity.normalizedJavaName}.get${attribute.setterGetterName}())<#elseif attribute.javaType=="char">new Character(${entity.normalizedJavaName}.get${attribute.setterGetterName}())<#else>${entity.normalizedJavaName}.get${attribute.setterGetterName}()</#if><#if attribute_has_next>, </#if>
		</#list>
		};
		
		String hql = "from ${outputPackageName}.model.${entity.javaName} ${entity.normalizedJavaName} where <#list entity.primaryKeyColumns as attribute>(${attribute.javaName})=?<#if attribute_has_next> and </#if></#list>";
		List rs = this.getHibernateTemplate().find(hql, keyParams);	
		${entity.javaName} ret = null;
		if (rs.size()==1)
		{
			ret = (${entity.javaName}) rs.get(0);
		}else if(rs.size()>1){
			ret = (${entity.javaName}) rs.get(0);
			log.warn("More than one Object found. Primarykey=" + ${entity.normalizedJavaName});
		}else{
			log.warn("Object not found. Primarykey=" + ${entity.normalizedJavaName});			
		}					
		if(log.isDebugEnabled()) log.debug("Exiting find${entity.javaName}ByKey() Primarykey=" + ${entity.normalizedJavaName});	
		return ret;
	}	
	
	</#if>
	
	
	
	/**
	* Insert a domain model into underline table.
	*/
	public ${entity.javaName} add${entity.javaName}(${entity.javaName} ${entity.normalizedJavaName})
	{
		if(log.isDebugEnabled()) log.debug("Entering add${entity.javaName}(${entity.javaName} model) ${entity.javaName}=" + ${entity.normalizedJavaName});
		Object key = (Object) this.getHibernateTemplate().save(${entity.normalizedJavaName});
		<#if entity.primaryKeyIntegerType >
			if(key!=null){
				<#switch entity.singlePrimaryKeyJavaType>
				  <#case "int">
			int intKey = ((Integer)key).intValue();
				<#list entity.primaryKeyColumns as attribute>
			${entity.normalizedJavaName}.set${attribute.setterGetterName}(intKey);
				</#list>			
				    <#break>
				  <#case "long">
			long longKey = ((Long)key).longValue();
				<#list entity.primaryKeyColumns as attribute>
			${entity.normalizedJavaName}.set${attribute.setterGetterName}(longKey);
				</#list>  
				    <#break>	
				 <#default>
				 if( key instanceof ${entity.javaName} ){
				 	${entity.normalizedJavaName} = (${entity.javaName})key;
				 }			 		  
				</#switch>	
			}	
		<#elseif entity.primaryKeyStringType >
			<#list entity.primaryKeyColumns as attribute>
			${entity.normalizedJavaName}.set${attribute.setterGetterName}((String)key);
			</#list> 
		</#if>
		if(log.isDebugEnabled()) log.debug("Exiting add${entity.javaName}(${entity.javaName} ${entity.normalizedJavaName}) ${entity.javaName}=" + ${entity.normalizedJavaName});	
		return ${entity.normalizedJavaName};	
	}
	
	
	/**
	* This method update underline row in relational database
	*/	
	public ${entity.javaName} update${entity.javaName}(${entity.javaName} ${entity.normalizedJavaName})
	{
		if(log.isDebugEnabled()) log.debug("Entering update${entity.javaName}(${entity.javaName} ${entity.normalizedJavaName}) ${entity.javaName}=" +${entity.normalizedJavaName});		
		this.getHibernateTemplate().update(${entity.normalizedJavaName});		
		if(log.isDebugEnabled()) log.debug("Exiting update${entity.javaName}(${entity.javaName} ${entity.normalizedJavaName}) ${entity.javaName}=" + ${entity.normalizedJavaName});	
		return ${entity.normalizedJavaName};
	}
	
	
	/**
	* This method delete underline row from relational database
	*/
	public ${entity.javaName} delete${entity.javaName}(${entity.javaName} ${entity.normalizedJavaName})
	{
		if(log.isDebugEnabled()) log.debug("Entering delete${entity.javaName}(${entity.javaName} ${entity.normalizedJavaName}) ${entity.javaName}=" + ${entity.normalizedJavaName});
		<#if entity.hasPrimaryKey >
		${entity.normalizedJavaName} =  delete${entity.javaName}ByKey(${entity.normalizedJavaName});
		<#else>
		  this.getHibernateTemplate().delete(${entity.normalizedJavaName});
		</#if>		
		if(log.isDebugEnabled()) log.debug("Exiting delete${entity.javaName}(${entity.javaName} ${entity.normalizedJavaName}) ${entity.javaName}=" + ${entity.normalizedJavaName});	
		return ${entity.normalizedJavaName} ;	
	}
	
	<#if entity.hasPrimaryKey >		
	
	/**
	* This method delete underline row from relational database
	* with model's primary key.
	*/	
	public ${entity.javaName} delete${entity.javaName}ByKey(<#list entity.primaryKeyColumns as attribute>${attribute.javaType} ${attribute.javaName} <#if attribute_has_next>, </#if></#list>)
	{
		if(log.isDebugEnabled()) log.debug("Entering delete${entity.javaName}ByKey()");
		${entity.javaName} ${entity.normalizedJavaName} = find${entity.javaName}ByKey(<#list entity.primaryKeyColumns as attribute>${attribute.javaName}<#if attribute_has_next>, </#if></#list>);		
		if(${entity.normalizedJavaName}!=null){
			this.getHibernateTemplate().delete(${entity.normalizedJavaName});
		}else{
			log.warn("Object not found in database, delete is ignored.");
		}
		if(log.isDebugEnabled()) log.debug("Exiting delete${entity.javaName}ByKey() Primarykey=" + ${entity.normalizedJavaName});	
		return ${entity.normalizedJavaName};
	}
	
	protected ${entity.javaName} delete${entity.javaName}ByKey(${entity.javaName} ${entity.normalizedJavaName})
	{
		if(log.isDebugEnabled()) log.debug("Entering delete${entity.javaName}ByKey() Primarykey=" + ${entity.normalizedJavaName});
		${entity.javaName} ret = find${entity.javaName}ByKey(${entity.normalizedJavaName});		
		if(ret!=null){
			this.getHibernateTemplate().delete(ret);
		}else{
			log.warn("Object not found in database, delete is ignored.");
		}
		if(log.isDebugEnabled()) log.debug("Exiting delete${entity.javaName}ByKey() Primarykey=" + ${entity.normalizedJavaName});	
		return ret;
	}	
	</#if>
}
